<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>自定义axios请求函数</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/qs/6.11.0/qs.js"></script>
  </head>
  <body>
    <button>点击发送 GET 请求</button>
    <button>点击发送 POST 请求</button>
    <button>点击发送 PUT 请求</button>
    <button>点击发送 DELETE 请求</button>

    <script>

      /* 
      1. 函数的返回值为promise, 成功的结果为response, 异常的结果为error
      2. 能处理多种类型的请求: GET/POST/PUT/DELETE
      3. 函数的参数为一个配置对象
        {

        ​	url: '',  // 请求地址

        ​	method: '',  // 请求方式GET/POST/PUT/DELETE

        ​	params: {},  // GET/DELETE请求的query参数

        ​	data: {}, // POST或PUT请求的请求体参数 

        }
      4. 响应json数据自动解析为js对象
      */
     function axios({url,method="GET",params={},data={}}) {
      return new Promise((resolve,reject)=>{

        // params也就是query参数需要放在地址内
        const queryStr = Qs.stringify(params); // 把params对象转成a=1&b=2的格式
        // 判断queryStr是否有值
        if (queryStr) {
          url += "?" + queryStr
        }

        // 防止请求方式是小写（改为统一的）
        method = method.toUpperCase();

        // 创建一个xhr 实例
        const xhr = new XMLHttpRequest();
        // 设置地址
        xhr.open(method,url);
        // 设置请求监听
        xhr.onreadystatechange = ()=>{
          // readyState状态码 0~4 4 代表响应内容解析完成，可以在客户端调用了
          if (xhr.readyState === 4) {
            // 状态码 200~299 代表请求成功
            if (xhr.status>=200 && xhr.status<300) {
              const resposen = {
                data:JSON.parse(xhr.responseText),
                status:xhr.status,
                statusText:xhr.statusText
              }
              resolve(resposen);
            } else {
              reject(new Error("请求失败 status=",xhr.status))
            }
          }
        }

        if (method === "GET") {
          xhr.send()
        } else {
          // 设置响应头  响应体数据的格式
          xhr.setRequestHeader('Content-Type','application/json')
          // 代表给服务器发请求  返回响应体数据
          xhr.send(JSON.stringify(data)); // 给浏览器返回数据 （必须json格式，因为上面设置的就是json）
        }
      })
     }

      /* 封装axios的静态方法 */

      axios.get = function (url, config) {
        return axios({...config, url, method: 'GET'})
      }
      axios.delete = function (url, config) {
        return axios({...config, url, method: 'DELETE'})
      }

      axios.post = function (url, data, config) {
        return axios({...config, url, method: 'post', data})
      }

      axios.put = function (url, data, config) {
        return axios({...config, url, method: 'put', data})
      }
    </script>

    <script>
      const buttons = document.querySelectorAll('button')


      buttons[0].onclick = async () => {
        try {
          // const response = await axios({
          //   method: 'GET',
          //   // url: 'http://localhost:3000/movie/2',
          //   url: 'http://localhost:3000/movie',
          //   params: { // 自动转换为query参数
          //     id: 2,
          //     name: '大话西游'
          //   }
          // })
          const response = await axios.get(
            'http://localhost:3000/movie',
            {
              params: { // 自动转换为query参数
                id: 2,
                name: '大话西游'
              }
            }
          )
          console.log(response)
        } catch (error) {
          console.log(error)
          alert(error.message)
        }
      }

      // 添加
      buttons[1].onclick = async () => {
        // const response = await axios({
        //   method: 'post',
        //   url: 'http://localhost:3000/movie',
        //   data: {
        //     name: 'AA',
        //     director: 'BB'
        //   }
        // })

        const response = await axios.post(
          'http://localhost:3000/movie',
          {
            name: 'AA2',
            director: 'BB2'
          }
        )
        console.log(response.data)
      }

      // 更新 
      buttons[2].onclick = async () => {
        // const response = await axios({
        //   method: 'put',
        //   url: 'http://localhost:3000/movie/14',
        //   data: { // 内部会自动转换为Json, 并指定相应Content-Type请求头
        //     name: '野外生存记13',
        //     director: '贝爷13'
        //   }
        // })
        const response = await axios.put(
          'http://localhost:3000/movie/15',
          { 
            name: '野外生存记13',
            director: '贝爷13'
          }
        )
        console.log(response.data)
      }

      // 删除
      buttons[3].onclick = async () => {
        // const response = await axios({
        //   method: 'delete',
        //   url: 'http://localhost:3000/movie/14',
        // })

        const response = await axios.delete('http://localhost:3000/movie/15')
        console.log(response.data)
      }

    </script>


  </body>
</html>

